// Copyright 2007-2009 Comdiv (F. Sadykov) - http://code.google.com/u/fagim.sadykov/
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// MODIFICATIONS HAVE BEEN MADE TO THIS FILE

using Boo.Lang.Compiler;
using Boo.Lang.Compiler.Ast;
using MvcContrib.Comdiv.Extensibility.BooLang;

#if MONORAIL
namespace Castle.MonoRail.Views.Brail
#else

namespace MvcContrib.Comdiv.ViewEngines.Brail
#endif
{
    /// <summary>
    /// COALESCE-like operator for output, 
    /// NOTE: uses Boo effective boolean (to work with IgnoreNull), so false values will be treatet as NULL, "" too
    /// isnull a,b,c(),d means:
    /// if a :
    ///     output a
    /// elif b :
    ///     output b
    /// elif c() :
    ///     output c()
    /// else:
    ///     output d
    /// NOTE: last parameter will be rendered even if it's null
    /// </summary>
    public class IsnullMacro :LexicalInfoPreservingMacro{
        protected override Statement ExpandImpl(MacroStatement macro){
            int i = 0;
            IfStatement parent = null;
            var target = new IfStatement();
            var result = target;
            foreach (var argument in macro.Arguments)
            {
                var condition = argument;
                var doer = new Block().add(BrailBuildingHelper.WriteOut(argument));
                if (argument is BinaryExpression)
                {
                    condition = ((BinaryExpression)argument).Left;
                    doer = new Block().add(BrailBuildingHelper.WriteOut(((BinaryExpression)argument).Right));
                }
                if ((i + 1) == macro.Arguments.Count && 1 != macro.Arguments.Count)
                {
                    parent.FalseBlock = doer;
                }
                else
                {
                    target.Condition = condition;
                    target.TrueBlock = doer;
                    if (parent != null)
                    {
                        var falser = new Block().add(target);
                        parent.FalseBlock = falser;
                    }
                }
                i++;
                parent = target;
                target = new IfStatement();
            }
            return result;
        }
    }
}